<!--用户管理-->
<!--created by lx 2023/2/15-->
<!--update by yuyupeng-->
<!--2023/03/16-->
<template>
  <div class="list-card-container">
    <a-card title="用户管理" class="general-card">
      <splitpanes class="default-theme">
        <pane min-size="10" size="18">
          <a-card title="组织机构树" class="general-card">
            <a-scrollbar style="height: 100%; overflow: auto">
              <a-skeleton v-if="treeData.length === 0" animation>
                <!-- 还在加载的时候用骨架屏先占个位子，好看点 -->
                <a-skeleton-line :rows="10" />
              </a-skeleton>
              <div v-else>
                <a-input-search
                  v-model="searchTreeKey"
                  style="margin-bottom: 5px"
                  @input="searchTreeData"
                />
                <a-tree
                  v-model:selected-keys="selectedTreeKeys"
                  v-model:expanded-keys="expandedTreeKeys"
                  block-node
                  :field-names="{
                    key: 'code',
                    title: 'name',
                    children: 'children',
                  }"
                  :data="treeDataFilter"
                  @select="onSelectTreeNode"
                >
                  <template #icon>
                    <icon-home />
                  </template>
                  <template #title="nodeData">
                    <span v-if="nodeData?.name.indexOf(searchTreeKey) > -1">
                      {{
                        nodeData?.name.substr(
                          0,
                          nodeData?.name.indexOf(searchTreeKey)
                        )
                      }}
                      <span style="color: #f50">{{ searchTreeKey }}</span>
                      {{
                        nodeData?.name.substr(
                          nodeData?.name.indexOf(searchTreeKey) +
                            searchTreeKey?.length
                        )
                      }}
                    </span>
                    <span v-else>{{ nodeData?.name }}</span>
                  </template>
                </a-tree>
              </div>
            </a-scrollbar>
          </a-card>
        </pane>
        <pane min-size="50" size="82">
          <a-card class="general-card">
            <!-- 查询表单 -->
            <AdvancedSearch
              ref="searchRef"
              :data-source="searchItemList"
              @change="searchByParams"
              @reset="resetAdvancedSearch"
            />
            <a-space style="margin-top: 5px; margin-bottom: 5px">
              <AdvancedDrawer
                ref="addRef"
                v-permission="['system:user:add']"
                click="button"
                title="新增用户信息"
                clickword="新增用户"
                :rules="advancedDrawerRules"
                :data-source="addDrawerConfig"
                :disabled="!currentSelectDeptTreeNode"
                @open="initAddDrawer"
                @select="selectChangeForAdvancedDrawer"
                @change="addDrawerSubmit"
              />

              <ImportUserModal @after-submit="getTbDataByPage" />

              <!--通过组织机构向批量用户进行角色授权-->
              <RoleDeptDrawer
                v-permission="['system:user:auth']"
                :dept-tree="treeData"
              />

              <a-button
                :disabled="selectedKeys.length === 0"
                @click="batchActivate"
              >
                批量激活
              </a-button>

              <!--通过组织机构激活用户-->
              <ActiveDeptDrawer
                v-permission="['system:user:auth']"
                @refresh="getTbDataByPage"
              />
              <!--根据表格中选中的用户进行批量授权-->
              <RoleBatchDrawer
                v-permission="['system:user:auth']"
                :user-ids="selectedKeys"
                :disabled="selectedKeys.length === 0"
              />

              <a-button
                v-permission="['system:user:delete']"
                :disabled="selectedKeys.length === 0"
                @click="openDeleteModal"
                ><icon-delete />批量删除</a-button
              >
            </a-space>
            <!-- 表格 -->
            <a-table
              v-model:selectedKeys="selectedKeys"
              row-key="id"
              column-resizable
              :columns="tbCols"
              :data="tbData"
              :row-selection="rowSelection"
              :pagination="pagination"
              :loading="tbLoading"
              :scroll="{ x: '100%', y: 400 }"
              :scrollbar="true"
              @page-change="onPageChange"
              @page-size-change="onPageSizeChange"
            >
              <!-- 插槽-详情 -->
              <template #detail="{ record }">
                <AdvancedShower
                  click="word"
                  title="人员详情"
                  clickword="详情"
                  :data-source="showDrawerConfig"
                  :data-record="record"
                />
              </template>
              <!-- 插槽-密级 -->
              <template #secretLevel="{ record }">
                <dictionary-tag
                  v-if="secretLevelDictDataSource.length > 0"
                  :key="record.secretLevel"
                  dict-type="userSecretLevel"
                  :dict-value="record.secretLevel"
                  :dict-data-source="secretLevelDictDataSource"
                />
              </template>
              <!-- 插槽-昵称 -->
              <template #nickname="{ record }">
                <dictionary-tag
                  v-if="nickNameDictDataSource.length > 0"
                  :key="record.nickname"
                  dict-type="nickname"
                  :dict-value="record.nickname"
                  :dict-data-source="nickNameDictDataSource"
                />
              </template>
              <!-- 插槽-部门 -->
              <template #deptCode="{ record }">
                {{ record.deptName }}
              </template>
              <!-- 插槽-一键复制 -->
              <template #quickCopyToolTip="{ record, column }">
                <quick-copy-tool-tip
                  :show-text="record[column['dataIndex']]"
                  show-btn
                />
              </template>
              <!--插槽: 性别-->
              <template #gender="{ record }">
                <a-tag v-if="record.gender" color="pinkpurple">
                  <icon-woman />女
                </a-tag>
                <a-tag v-else color="blue"><icon-man />男</a-tag>
              </template>
              <!--插槽: 状态是否激活-->
              <template #activated="{ record }">
                <a-tag v-if="record.activated === 'true'" color="#00b42a"
                  >已激活</a-tag
                >
                <a-tag v-else color="#86909c">未激活</a-tag>
              </template>
              <!-- 插槽：状态 -->
              <template #status="{ record }">
                <a-tag v-if="record.status === 0" color="#00b42a">正常</a-tag>
                <a-tag v-if="record.status === 1" color="#86909c">停用</a-tag>
              </template>
              <!-- 插槽-操作 -->
              <template #operation="{ record }">
                <a-space
                  v-permission="[
                    'system:user:auth',
                    'system:user:edit',
                    'system:user:delete',
                    'system:user:activate',
                    'system:user:disable',
                  ]"
                >
                  <!-- 按钮: 授权 -->
                  <RoleDrawer
                    v-permission="['system:user:auth']"
                    :disabled="record.activated !== 'true'"
                    :user-id="record.id"
                  />
                  <AdvancedDrawer
                    v-permission="['system:user:edit']"
                    click="link"
                    title="修改用户信息"
                    clickword="修改"
                    :rules="advancedDrawerRules"
                    :data-source="editDrawerConfig"
                    :data-record="record"
                    @open="initEditDrawer(record)"
                    @select="selectChangeForAdvancedDrawer"
                    @change="(req) => editDrawerSubmit(req, record)"
                  />
                  <a-popconfirm
                    content="确定删除吗?"
                    type="warning"
                    @ok="deleteTbData(record.id)"
                  >
                    <a-link v-permission="['system:user:delete']" type="text">
                      删除
                    </a-link>
                  </a-popconfirm>
                  <a-dropdown>
                    <a-link
                      v-permission="[
                        'system:user:activate',
                        'system:user:disable',
                        'system:user:setsecretlevel',
                      ]"
                    >
                      更多
                      <icon-down />
                    </a-link>
                    <template #content>
                      <a-doption
                        v-permission="['system:user:activate']"
                        :disabled="record.activated === 'true'"
                        @click="activateUser(record)"
                        >激活</a-doption
                      >
                      <a-doption
                        v-permission="['system:user:disable']"
                        @click="toggleUserStatus(record)"
                      >
                        {{ record.status === 0 ? '禁用' : '启用' }}
                      </a-doption>
                      <a-doption
                        v-permission="['system:user:setsecretlevel']"
                        @click="openSetSecretLevelModal(record)"
                      >
                        设置密级
                      </a-doption>
                    </template>
                  </a-dropdown>
                </a-space>
              </template>
            </a-table>
          </a-card>
        </pane>
      </splitpanes>
    </a-card>
    <!-- 修改用户密级弹窗 -->
    <AdvancedFormModal
      ref="setSecretLevelModalRef"
      width="600px"
      title="修改密级"
      :items="setSecretLevelModalConfig"
      @ok="setSecretLevelModalSubmit"
    />
  </div>
</template>

<!--新script-->
<script lang="ts" setup>
  import {
    Message,
    Modal,
    Notification,
    TableColumnData,
    TableRowSelection,
  } from '@arco-design/web-vue';
  import { queryDeptRecordTreeList } from '@/api/system/dept';
  import {
    queryUserRecordList,
    saveUserRecord,
    updateUserRecord,
    activeUserRecord,
    activeUserBatch,
    updateUserStatus,
    deleteUserRecords,
    setUserSecretLevel,
  } from '@/api/system/user';
  import { ref, onMounted, reactive, watch } from 'vue';
  import AdvancedSearch from '@/common/components/cac-components/advanced-search/index.vue';
  import AdvancedDrawer from '@/common/components/cac-components/advanced-drawer/index.vue';
  import AdvancedShower from '@/common/components/cac-components/advanced-shower/index.vue';
  import AdvancedFormModal from '@/common/components/cac-components/advanced-form-modal/index.vue';
  import QuickCopyToolTip from '@/common/components/cac-components/quickcopy-tooltip/index.vue';
  import DictionaryTag from '@/common/components/cac-components/dictionary-tag/index.vue';
  import { Pagination } from '@/types/global';
  import { Splitpanes, Pane } from 'splitpanes';
  import 'splitpanes/dist/splitpanes.css';
  import { UserParams, UserRecord } from '@/api/system/model/userModel';
  import {
    DictDataParamsSort,
    DictDataRecord,
  } from '@/api/system/model/dictDataModel';
  import { queryDictDataRecordList } from '@/api/system/dictionary';
  import RoleDrawer from './components/role-drawer.vue';
  import RoleDeptDrawer from './components/role-dept-drawer.vue';
  import ActiveDeptDrawer from './components/activ-dept-drawer.vue';
  import RoleBatchDrawer from './components/role-batch-drawer.vue';
  import ImportUserModal from './components/import-user-modal.vue';

  /**
   * data
   */
  const treeData = ref<any[]>([]); // 树
  const treeDataFilter = ref<any[]>([]); // 用于搜索的过滤树
  const filterKeySet = new Set(); // 定义一个集合，用于记录过滤keys
  const searchTreeKey = ref<string>(); // 树顶上的搜索框关键字
  const dataList = ref<any[]>([]); // treeData的所有key:title:id
  const parentKeys = ref<string[]>([]); // 用于存储点击的树节点的所有父节点的key
  const currentSelectDeptTreeNode = ref<any>(); // 记录当前选中的左侧组织机构树节点
  const currentDrawerSelectDeptId = ref<string>(); // 记录新增和编辑抽屉中当前选中的部门的主键id
  const nickNameDictDataSource = ref<DictDataRecord[]>([]); // 昵称数据字典数据源
  const secretLevelDictDataSource = ref<DictDataRecord[]>([]); // 人员密级数据字典数据源
  const setSecretLevelModalRef = ref<any>();
  // 表格
  const tbData = ref<UserRecord[]>([]);
  const tbCols: TableColumnData[] = [
    {
      title: '序号',
      align: 'center',
      dataIndex: 'index',
      fixed: 'left',
      width: 60,
      render: (row: any) => row.rowIndex + 1,
    },
    /* { title: '主键', dataIndex: 'id', fixed: 'left', ellipsis: true, align: 'center', tooltip: true }, */
    {
      title: '查看',
      fixed: 'left',
      align: 'center',
      width: 100,
      slotName: 'detail',
    },
    {
      title: '用户名',
      dataIndex: 'username',
      width: 150,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '用户工号',
      dataIndex: 'userCode',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '密级',
      dataIndex: 'secretLevel',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'secretLevel',
    },
    {
      title: '是否激活',
      dataIndex: 'activated',
      width: 120,
      align: 'center',
      slotName: 'activated',
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 120,
      align: 'center',
      slotName: 'status',
    },
    {
      title: '性别',
      dataIndex: 'gender',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'gender',
    },
    // {
    //   title: '用户昵称',
    //   dataIndex: 'nickname',
    //   width: 150,
    //   ellipsis: true,
    //   align: 'center',
    //   tooltip: true,
    //   slotName: 'nickname',
    // },
    /* { title: '头像地址', dataIndex: 'avatar', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' }, */
    {
      title: '人员类别',
      dataIndex: 'category',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    /* { title: '数据密级(0:公开,5内部,6秘密,7机密,8绝密)', dataIndex: 'secretLevel', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '身份证号', dataIndex: 'idNumber', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' }, */
    {
      title: '学历',
      dataIndex: 'degree',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '联系电话',
      dataIndex: 'mobile',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '用户邮箱',
      dataIndex: 'email',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '部门',
      dataIndex: 'deptCode',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'deptCode',
    },
    {
      title: '出生日期',
      dataIndex: 'birthday',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '入职日期',
      dataIndex: 'entryTime',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '政治面貌',
      dataIndex: 'polity',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    {
      title: '职称',
      dataIndex: 'title',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    /* { title: '地址', dataIndex: 'address', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '人员状态，默认0，正常', dataIndex: 'status', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' }, */
    {
      title: '备注',
      dataIndex: 'remark',
      width: 150,
      ellipsis: true,
      align: 'center',
      tooltip: true,
      slotName: 'quickCopyToolTip',
    },
    /* { title: '所属组织机构ID(多组织机构时需要,非必须)', dataIndex: 'orgId', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '部门ID', dataIndex: 'deptId', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '创建者', dataIndex: 'creator', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '创建时间', dataIndex: 'createTime', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '更新者', dataIndex: 'updater', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '更新时间', dataIndex: 'updateTime', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '更新ip', dataIndex: 'updateIp', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '是否删除(非必须)', dataIndex: 'deleted', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '乐观锁', dataIndex: 'version', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' },
  { title: '租户编号', dataIndex: 'tenantId', width: 150, ellipsis: true, align: 'center', tooltip: true, slotName: 'quickCopyToolTip' }, */
    {
      title: '操作',
      align: 'center',
      fixed: 'right',
      width: 220,
      slotName: 'operation',
    },
  ];
  const searchRef = ref<any>();
  const addRef = ref<any>();
  const tbLoading = ref<boolean>(false);
  const currentSearchParams = ref<UserRecord>({}); // 记录当前的搜索条件
  const treeDataLoading = ref<boolean>(false); // 指示树形组件是否正在加载中
  const expandedTreeKeys = ref<string[]>([]); // 已展开的树节点keys
  const selectedTreeKeys = ref<string[]>([]); // 已选中的树节点keys
  // 勾选框
  const selectedKeys = ref([]);
  const rowSelection: TableRowSelection = reactive({
    type: 'checkbox',
    showCheckedAll: true,
    onlyCurrent: false,
  });
  // 分页，默认第1页，每页10条
  const basePagination: Pagination = {
    current: 1,
    pageSize: 10,
    showPageSize: true,
    showTotal: true,
  };
  const pagination = reactive({
    ...basePagination,
  });
  // 搜索项配置
  const searchItemList = [
    {
      type: 'text',
      labelText: '用户名',
      fieldName: 'username',
    },
    {
      type: 'text',
      labelText: '用户工号',
      fieldName: 'userCode',
    },
    {
      type: 'select-tree',
      labelText: '部门',
      fieldName: 'deptCode',
      codefield: 'code',
      namefield: 'name',
      data: treeData,
      allowClear: false,
    },
  ];
  // 新增抽屉配置项
  const addDrawerConfig = [
    /* { type: 'text', labelText: '主键', fieldName: 'id'}, */
    {
      type: 'text',
      labelText: '用户名',
      fieldName: 'username',
    },
    {
      type: 'text',
      labelText: '用户工号',
      fieldName: 'userCode',
    },
    /* { type: 'text', labelText: '头像地址', fieldName: 'avatar'}, */
    // {
    //   type: 'dictionary',
    //   labelText: '用户昵称',
    //   fieldName: 'nickname',
    //   dictType: 'nickname',
    // },
    { type: 'text', labelText: '人员类别', fieldName: 'category' },
    /* { type: 'text', labelText: '数据密级(0:公开,5内部,6秘密,7机密,8绝密)', fieldName: 'secretLevel'},
    { type: 'text', labelText: '身份证号', fieldName: 'idNumber'}, */
    {
      type: 'select',
      labelText: '性别',
      fieldName: 'gender',
      codefield: 'value',
      namefield: 'label',
      options: [
        { label: '女', value: 1 },
        { label: '男', value: 0 },
      ],
      initialValue: 0,
    },
    { type: 'text', labelText: '学历', fieldName: 'degree' },
    { type: 'text', labelText: '联系电话', fieldName: 'mobile' },
    { type: 'text', labelText: '用户邮箱', fieldName: 'email' },
    {
      type: 'select-tree',
      labelText: '部门',
      fieldName: 'deptCode',
      codefield: 'code',
      namefield: 'name',
      data: treeData,
      allowClear: false,
    },
    {
      type: 'datetime',
      labelText: '出生日期',
      fieldName: 'birthday',
      format: 'YYYY-MM-DD',
    },
    {
      type: 'datetime',
      labelText: '入职日期',
      fieldName: 'entryTime',
      format: 'YYYY-MM-DD',
    },
    {
      type: 'select',
      labelText: '政治面貌',
      fieldName: 'polity',
      codefield: 'value',
      namefield: 'label',
      options: [
        { label: '群众', value: '群众' },
        { label: '团员', value: '团员' },
        { label: '党员', value: '党员' },
        { label: '其他', value: '其他' },
      ],
    },
    { type: 'text', labelText: '备注', fieldName: 'remark' },
    /* { type: 'text', labelText: '地址', fieldName: 'address'},
    { type: 'text', labelText: '职称', fieldName: 'title'},
    { type: 'text', labelText: '人员状态，默认0，正常', fieldName: 'status'},
    { type: 'text', labelText: '所属组织机构ID(多组织机构时需要,非必须)', fieldName: 'orgId'},
    { type: 'text', labelText: '所属部门ID(非必须)', fieldName: 'deptId'},
    { type: 'text', labelText: '创建者', fieldName: 'creator'},
    { type: 'text', labelText: '创建时间', fieldName: 'createTime'},
    { type: 'text', labelText: '更新者', fieldName: 'updater'},
    { type: 'text', labelText: '更新时间', fieldName: 'updateTime'},
    { type: 'text', labelText: '更新ip', fieldName: 'updateIp'},
    { type: 'text', labelText: '是否删除(非必须)', fieldName: 'deleted'},
    { type: 'text', labelText: '乐观锁', fieldName: 'version'},
    { type: 'text', labelText: '租户编号', fieldName: 'tenantId'}, */
  ];
  // 修改抽屉配置项
  const editDrawerConfig = [
    /* {
      type: 'text',
      labelText: '主键',
      fieldName: 'id',
      disabled: true,
    }, */
    {
      type: 'text',
      labelText: '用户名',
      fieldName: 'username',
    },
    {
      type: 'text',
      labelText: '用户工号',
      fieldName: 'userCode',
    },
    /* { type: 'text', labelText: '头像地址', fieldName: 'avatar'}, */
    // {
    //   type: 'dictionary',
    //   labelText: '用户昵称',
    //   fieldName: 'nickname',
    //   dictType: 'nickname',
    // },
    { type: 'text', labelText: '人员类别', fieldName: 'category' },
    /* { type: 'text', labelText: '数据密级(0:公开,5内部,6秘密,7机密,8绝密)', fieldName: 'secretLevel'},
    { type: 'text', labelText: '身份证号', fieldName: 'idNumber'}, */
    {
      type: 'select',
      labelText: '性别',
      fieldName: 'gender',
      codefield: 'value',
      namefield: 'label',
      options: [
        { label: '女', value: 1 },
        { label: '男', value: 0 },
      ],
    },
    { type: 'text', labelText: '学历', fieldName: 'degree' },
    { type: 'text', labelText: '联系电话', fieldName: 'mobile' },
    { type: 'text', labelText: '用户邮箱', fieldName: 'email' },
    {
      type: 'select-tree',
      labelText: '部门',
      fieldName: 'deptCode',
      codefield: 'code',
      namefield: 'name',
      data: treeData,
      allowClear: false,
    },
    {
      type: 'datetime',
      labelText: '出生日期',
      fieldName: 'birthday',
      format: 'YYYY-MM-DD',
    },
    {
      type: 'datetime',
      labelText: '入职日期',
      fieldName: 'entryTime',
      format: 'YYYY-MM-DD',
    },
    {
      type: 'select',
      labelText: '政治面貌',
      fieldName: 'polity',
      codefield: 'value',
      namefield: 'label',
      options: [
        { label: '群众', value: '群众' },
        { label: '团员', value: '团员' },
        { label: '党员', value: '党员' },
        { label: '其他', value: '其他' },
      ],
    },
    { type: 'text', labelText: '备注', fieldName: 'remark' },
    /* { type: 'text', labelText: '地址', fieldName: 'address'},
    { type: 'text', labelText: '职称', fieldName: 'title'},
    { type: 'text', labelText: '人员状态，默认0，正常', fieldName: 'status'},
    { type: 'text', labelText: '所属组织机构ID(多组织机构时需要,非必须)', fieldName: 'orgId'},
    { type: 'text', labelText: '所属部门ID(非必须)', fieldName: 'deptId'},
    { type: 'text', labelText: '创建者', fieldName: 'creator'},
    { type: 'text', labelText: '创建时间', fieldName: 'createTime'},
    { type: 'text', labelText: '更新者', fieldName: 'updater'},
    { type: 'text', labelText: '更新时间', fieldName: 'updateTime'},
    { type: 'text', labelText: '更新ip', fieldName: 'updateIp'},
    { type: 'text', labelText: '是否删除(非必须)', fieldName: 'deleted'},
    { type: 'text', labelText: '乐观锁', fieldName: 'version'},
    { type: 'text', labelText: '租户编号', fieldName: 'tenantId'}, */
  ];
  // 抽屉表单项校验配置
  const advancedDrawerRules = ref({
    userCode: [{ required: true, message: '请输入用户工号' }],
    username: [{ required: true, message: '请输入用户名' }],
    deptCode: [{ required: true, message: '请选择部门' }],
  });
  // 详情抽屉配置项
  const showDrawerConfig = [
    /* { type: 'text', labelText: '主键', fieldName: 'id'}, */
    {
      type: 'text',
      labelText: '用户名',
      fieldName: 'username',
    },
    {
      type: 'text',
      labelText: '用户工号',
      fieldName: 'userCode',
    },
    {
      type: 'select',
      labelText: '是否激活',
      fieldName: 'activated',
      codefield: 'value',
      namefield: 'label',
      options: [
        { label: '是', value: 'true' },
        { label: '否', value: 'false' },
      ],
    },
    /* { type: 'text', labelText: '头像地址', fieldName: 'avatar'}, */
    // {
    //   type: 'dictionary',
    //   labelText: '用户昵称',
    //   fieldName: 'nickname',
    //   dictType: 'nickname',
    // },
    { type: 'text', labelText: '人员类别', fieldName: 'category' },
    /* { type: 'text', labelText: '数据密级(0:公开,5内部,6秘密,7机密,8绝密)', fieldName: 'secretLevel'},
    { type: 'text', labelText: '身份证号', fieldName: 'idNumber'}, */
    {
      type: 'select',
      labelText: '性别',
      fieldName: 'gender',
      codefield: 'value',
      namefield: 'label',
      options: [
        { label: '女', value: 1 },
        { label: '男', value: 0 },
      ],
    },
    { type: 'text', labelText: '学历', fieldName: 'degree' },
    { type: 'text', labelText: '联系电话', fieldName: 'mobile' },
    { type: 'text', labelText: '用户邮箱', fieldName: 'email' },
    {
      type: 'select-tree',
      labelText: '部门',
      fieldName: 'deptCode',
      codefield: 'code',
      namefield: 'name',
      data: treeData,
      allowClear: false,
    },
    {
      type: 'datetime',
      labelText: '出生日期',
      fieldName: 'birthday',
      format: 'YYYY-MM-DD',
    },
    {
      type: 'datetime',
      labelText: '入职日期',
      fieldName: 'entryTime',
      format: 'YYYY-MM-DD',
    },
    {
      type: 'select',
      labelText: '政治面貌',
      fieldName: 'polity',
      codefield: 'value',
      namefield: 'label',
      options: [
        { label: '群众', value: '群众' },
        { label: '团员', value: '团员' },
        { label: '党员', value: '党员' },
        { label: '其他', value: '其他' },
      ],
    },
    { type: 'text', labelText: '备注', fieldName: 'remark' },
    /* { type: 'text', labelText: '地址', fieldName: 'address'},
    { type: 'text', labelText: '职称', fieldName: 'title'},
    { type: 'text', labelText: '人员状态，默认0，正常', fieldName: 'status'},
    { type: 'text', labelText: '所属组织机构ID(多组织机构时需要,非必须)', fieldName: 'orgId'},
    { type: 'text', labelText: '所属部门ID(非必须)', fieldName: 'deptId'},
    { type: 'text', labelText: '创建者', fieldName: 'creator'},
    { type: 'text', labelText: '创建时间', fieldName: 'createTime'},
    { type: 'text', labelText: '更新者', fieldName: 'updater'},
    { type: 'text', labelText: '更新时间', fieldName: 'updateTime'},
    { type: 'text', labelText: '更新ip', fieldName: 'updateIp'},
    { type: 'text', labelText: '是否删除(非必须)', fieldName: 'deleted'},
    { type: 'text', labelText: '乐观锁', fieldName: 'version'},
    { type: 'text', labelText: '租户编号', fieldName: 'tenantId'}, */
  ];
  // 修改密级弹窗配置项
  const setSecretLevelModalConfig = [
    {
      span: 24,
      type: 'text',
      labelText: 'id',
      fieldName: 'id',
      visible: false,
    },
    {
      type: 'text',
      labelText: '用户工号',
      fieldName: 'userCode',
      disabled: true,
    },
    {
      type: 'text',
      labelText: '用户名',
      fieldName: 'username',
      disabled: true,
    },
    {
      span: 24,
      type: 'dictionary',
      labelText: '密级',
      fieldName: 'secretLevel',
      dictType: 'userSecretLevel',
    },
  ];
  /**
   * watch
   */
  watch(
    () => parentKeys,
    (val) => {
      if (val) {
        val.value.forEach((element: any) => {
          filterKeySet.add(element);
        });
        // 进行过滤操作
        treeDataFilter.value = treeData.value.filter((item) =>
          filterKeySet.has(item.code)
        );
        expandedTreeKeys.value = [...filterKeySet] as string[];
      }
    },
    { deep: true, immediate: true }
  );
  /**
   * func
   */
  /**
   * @description 获取部门的树形结构信息
   */
  const getTreeData = async () => {
    treeDataLoading.value = true;
    treeData.value = [];
    treeDataFilter.value = [];
    try {
      const { data } = await queryDeptRecordTreeList({});
      treeData.value = data;
      treeDataFilter.value = data;
      dataList.value = [];
      generateList(treeData.value);
    } catch (error) {
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
        duration: 20000,
      });
    } finally {
      treeDataLoading.value = false;
    }
  };
  /**
   * @description 构建treeData的所有 { key: title: id } 数组
   * @param data 树节点数据
   */
  const generateList = (data: any) => {
    // 创建dataList 递归调用
    data.forEach((item: any) => {
      const node = item;
      const key = node.code;
      dataList.value.push({ key, title: node.name, id: node.id });
      if (node.children) {
        generateList(node.children);
      }
    });
  };
  /**
   * @description 根据子节点的key获取父节点的key
   * @param key key
   * @param tree 树节点
   */
  const getParentKey = (key: string, tree: any) => {
    let parentKey;
    tree.forEach((elem: any) => {
      const node = elem;
      if (node.children) {
        if (node.children.some((item: any) => item.code === key)) {
          parentKey = node.code;
        } else if (getParentKey(key, node.children)) {
          parentKey = getParentKey(key, node.children);
        }
      }
    });
    return parentKey;
  };
  /**
   * @description 获取完整地父节点的key数组 递归调用
   * @param key
   */
  const getWholeParentKeys = (key: string) => {
    const temp = getParentKey(key, treeData.value);
    if (temp !== undefined) {
      parentKeys.value.push(temp);
      getWholeParentKeys(temp);
    }
  };
  /**
   * @description 树形结构上面的搜索框发生改变会触发此函数
   * @param value
   */
  const searchTreeData = (val: any) => {
    const value = val.replaceAll(' ', '');
    filterKeySet.clear();
    // 进行搜索操作
    const expandedKeysTemp = [] as any[];
    dataList.value.forEach((item) => {
      if (item.title && item.title.indexOf(value) > -1) {
        expandedKeysTemp.push(item.key);
      }
    });
    parentKeys.value = [];
    // 必须要有下面这个forEach，否则只能查到2层数据，因为超过了2层后匹配不到更上层的父id，进而导致搜索不出结果
    expandedKeysTemp.forEach((item: string) => {
      filterKeySet.add(item);
      getWholeParentKeys(item); // 把原始的expandedKeysTemp中的每个key对应的完整父key都放进parentKeys保存
    });
    expandedTreeKeys.value =
      value.trim().length === 0 ? [] : ([...filterKeySet] as string[]);
    searchTreeKey.value = value;
    // 进行过滤操作
    treeDataFilter.value = treeData.value.filter((item) =>
      filterKeySet.has(item.code)
    );
  };
  /**
   * @description 根据dictType获取该型字典的所有数据
   * @param dictType 字典类型编码
   */
  const getDictDataDataSource = async (dictType: string) => {
    const params: DictDataParamsSort = {
      dictType,
      orderField: 'sort', // 对sort字段进行排序
      order: 'asc', // 排序方式，分为asc升序 desc降序
    };
    try {
      const { data } = await queryDictDataRecordList(params);
      return data;
    } catch (error) {
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
      });
      return [];
    }
  };
  /**
   * @method
   * @description 获取表格数据
   */
  const getTbDataByPage = async () => {
    const params: UserParams = {
      page: pagination.current,
      limit: pagination.pageSize,
      ...currentSearchParams.value, // 按条件搜索，如果有的话
    };
    tbLoading.value = true;
    selectedKeys.value = [];
    try {
      const { data } = await queryUserRecordList(params);
      data.list.forEach((item: any) => {
        item.activated = item.activated ? 'true' : 'false'; // 这个true和false要用单引号包一层，否则select组件不认识boolean类型的初始值
        item.secretLevel = String(item.secretLevel); // 用户密级也要用单引号包一层，否则数据字典组件不认识number类型的值
      });
      tbData.value = data.list;
      pagination.total = Number(data.total); // 用Number函数转一下，否则f12控制台会有警告，很不好看
      setTimeout(() => {
        // 等2秒钟后再设置部门名称，以免dataList还没构建完成
        setDeptName();
      }, 2000);
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
        duration: 20000,
      });
    } finally {
      tbLoading.value = false;
    }
  };
  /**
   * @method
   * @description 按条件搜索
   */
  const searchByParams = (reqdata: UserRecord = {}) => {
    pagination.current = 1;
    currentSearchParams.value = reqdata;
    getTbDataByPage();
  };
  /**
   * @method
   * @description 搜索组件清空后触发
   */
  const resetAdvancedSearch = () => {
    selectedTreeKeys.value = []; // 搜索组件清空会触发不带条件的搜素，因此要把已选中的树节点keys清空
    currentSelectDeptTreeNode.value = undefined; // 记录的当前选中的左侧组织机构树节点也要重置
  };
  /**
   * @method
   * @description 页码发生变化触发
   */
  const onPageChange = (current: number) => {
    pagination.current = current;
    getTbDataByPage();
  };
  /**
   * @method
   * @description 数据条数发生变化触发
   */
  const onPageSizeChange = (pageSize: number) => {
    pagination.pageSize = pageSize;
    getTbDataByPage();
  };
  /**
   * @description 打开新增抽屉的时候对数据进行一些初始化的操作
   */
  const initAddDrawer = () => {
    currentDrawerSelectDeptId.value = currentSelectDeptTreeNode.value.id;
    setTimeout(() => {
      // 等1s再渲染默认部门，否则渲染不上去
      addRef.value.setFormValues({
        deptCode: currentSelectDeptTreeNode.value.code,
      });
    }, 1000);
  };
  /**
   * @method
   * @description 新增抽屉提交
   */
  const addDrawerSubmit = async (reqdata: any) => {
    reqdata.deptId = currentDrawerSelectDeptId.value || '';
    try {
      const res = (await saveUserRecord(reqdata)) as any;
      if (res.code === 200) {
        Notification.success({
          content: '保存成功！',
        });
      } else {
        Notification.error({
          title: '保存失败！',
          content: res.message,
        });
      }
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
        duration: 20000,
      });
    } finally {
      await getTbDataByPage();
    }
  };
  /**
   * @description 打开编辑抽屉的时候对数据进行一些初始化的操作
   * @param record
   */
  const initEditDrawer = (record: any) => {
    currentDrawerSelectDeptId.value = record.deptId || '';
  };
  /**
   * @description 抽屉中select类型组件变化的监听反馈
   * @param value 值
   * @param name 属性名
   */
  const selectChangeForAdvancedDrawer = (value: string, name: string) => {
    if (name === 'deptCode') {
      // 根据部门编号deptCode获取部门主键id, 新增和修改用户接口要用
      currentDrawerSelectDeptId.value = dataList.value.filter(
        (el) => el.key === value
      )[0].id;
    }
  };
  /**
   * @method
   * @description 修改抽屉提交
   */
  const editDrawerSubmit = async (reqdata: any, record: UserRecord) => {
    reqdata.id = record.id;
    reqdata.deptId = currentDrawerSelectDeptId.value || '';
    try {
      const res = (await updateUserRecord(reqdata)) as any;
      if (res.code === 200) {
        Notification.success({
          content: '修改成功！',
        });
      } else {
        Notification.error({
          title: '修改失败！',
          content: res.message,
        });
      }
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
        duration: 20000,
      });
    } finally {
      await getTbDataByPage();
    }
  };
  /**
   * @description 激活用户
   * @param row
   */
  const activateUser = async (row: UserRecord) => {
    try {
      await activeUserRecord({ id: row.id });
      Message.success('激活成功');
    } finally {
      await getTbDataByPage();
    }
  };
  // 批量激活
  const batchActivate = async () => {
    try {
      const list = selectedKeys.value.filter((key) => {
        return tbData.value.find(
          (elem) => elem.id === key && elem.activated !== 'true'
        );
      });
      if (list.length > 0) {
        console.log('list', list);
        await activeUserBatch(list);
        Message.success('激活成功');
      } else {
        Message.info('用户已激活');
      }
    } finally {
      getTbDataByPage();
    }
  };
  /**
   * @method
   * @description 删除用户信息
   */
  const deleteTbData = async (id: string) => {
    const reqdata = [];
    reqdata.push(id);
    try {
      const res = (await deleteUserRecords(reqdata)) as any;
      if (res.code === 200) {
        Notification.success({
          content: '删除成功！',
        });
      } else {
        Notification.error({
          title: '删除失败！',
          content: res.message,
        });
      }
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
        duration: 20000,
      });
    } finally {
      await getTbDataByPage();
    }
  };

  // 提示框：批量删除
  const openDeleteModal = () => {
    Modal.warning({
      title: '删除用户',
      content: `确认删除所选中的 ${selectedKeys.value.length} 个用户？`,
      hideCancel: false,
      onOk: deleteTbDataList,
    });
  };
  /**
   * @method
   * @description 批量删除用户，传id数组，支持批量
   */
  const deleteTbDataList = async () => {
    try {
      const res = (await deleteUserRecords(selectedKeys.value)) as any;
      if (res.code === 200) {
        Notification.success({
          content: '删除成功！',
        });
      } else {
        Notification.error({
          title: '删除失败！',
          content: res.message,
        });
      }
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
        duration: 20000,
      });
    } finally {
      await getTbDataByPage();
    }
  };

  // 启用用户
  const toggleUserStatus = async (record: UserRecord) => {
    try {
      await updateUserStatus({
        id: record.id,
        status: record.status === 1 ? 0 : 1,
      });
      Message.success('更新成功');
    } finally {
      await getTbDataByPage();
    }
  };

  /**
   * 打开设置密级对话框
   * @param record
   */
  const openSetSecretLevelModal = (record: UserRecord) => {
    setSecretLevelModalRef.value.open({
      id: record.id,
      userCode: record.userCode,
      username: record.username,
      secretLevel: record.secretLevel,
    });
  };

  /**
   * 点击树节点触发
   * @param newSelectedKeys
   * @param event
   */
  const onSelectTreeNode = (newSelectedKeys: any, event: any) => {
    selectedTreeKeys.value = newSelectedKeys;
    currentSelectDeptTreeNode.value = event.node;
    if (event.node.children) {
      let flag = false;
      expandedTreeKeys.value.forEach((item: string) => {
        if (item === newSelectedKeys[0]) {
          flag = true;
        }
      });
      if (!flag) {
        expandedTreeKeys.value.push(newSelectedKeys[0]);
      }
    }
    searchRef.value.setFormValues({ deptCode: newSelectedKeys[0] }); // 给搜索组件设置对应的部门编码
    pagination.current = 1;
    currentSearchParams.value = { deptCode: newSelectedKeys[0] };
    getTbDataByPage(); // 按条件查询，注意：这里不能用searchRef.value.handleSubmit();方法，会滞后一步，可能是setFormValues内部还没遍历结束就handleSubmit了一下
  };
  // /**
  //  * 展开树节点触发
  //  * @param newExpandedKeys
  //  * @param event
  //  */
  // const onExpandTreeNode = (newExpandedKeys: any, event: any) => {
  // };
  /**
   * @description 根据deptCode给tbData设置部门名称
   */
  const setDeptName = () => {
    tbData.value.forEach((elem: any) => {
      elem.deptName = dataList.value.filter(
        (el) => el.key === elem.deptCode
      )[0].title;
    });
  };
  /**
   * @method
   * @description 修改密级弹窗提交
   */
  const setSecretLevelModalSubmit = async (reqdata: any) => {
    try {
      const req = {
        id: reqdata.id,
        secretLevel: reqdata.secretLevel,
      };
      const res = (await setUserSecretLevel(req)) as any;
      if (res.code === 200) {
        Notification.success({
          content: '修改成功！',
        });
      } else {
        Notification.error({
          title: '修改失败！',
          content: res.message,
        });
      }
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
      });
    } finally {
      await getTbDataByPage();
    }
  };
  /**
   * onMounted
   */
  onMounted(() => {
    getTreeData();
    getTbDataByPage();
    getDictDataDataSource('nickname').then((result) => {
      // 昵称数据字典数据源
      nickNameDictDataSource.value = result;
    });
    getDictDataDataSource('userSecretLevel').then((result) => {
      // 人员密级数据字典数据源
      secretLevelDictDataSource.value = result;
    });
  });
</script>

<style scoped lang="less">
  .list-card-container {
    height: 100%;
    padding: 20px;

    /* background-color: var(--color-bg-1); */
    border-radius: var(--border-radius-default);
  }
</style>
